package cn.woblog.android.downloader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

import cn.woblog.android.downloader.bean.DownloadInfo;
import cn.woblog.android.downloader.bean.DownloadStatus;
import cn.woblog.android.downloader.callback.OnDownloadListener;
import cn.woblog.android.common.db.DBController;
import cn.woblog.android.downloader.excetpion.PauseException;
import cn.woblog.android.common.utils.Const;
import cn.woblog.android.common.utils.Logs;


public class DownloadThread extends Thread {
	private static final String TAG = "DownloadThread";
	private static final String NOT_ENCODE_VIDEO_URL = "http://m5-q.highso.com.cn";
	private DownloadInfo data;
	private long lastProgress;
	//	private long size;
	private OnDownloadListener listener;
	private DBController db;
	private boolean isPause;
	private boolean isStop;
	private int retryCount = 0;

	public DownloadThread(DownloadInfo data, OnDownloadListener listener, DBController db) {
		this.data = data;
		this.db = db;
		this.listener = listener;
		lastProgress = data.getProgress();
	}

	@Override
	public void run() {
		while (!isStop) {
			try {
				checkPause();
				lastProgress = data.getProgress();

				FileOutputStream fileOutputStream = new FileOutputStream(data.getPath(), true);

				HttpURLConnection connection = getHttpUrlConnection(true, data.getUrl(), lastProgress, data.getSize());
				connection.connect();
				int responseCode = connection.getResponseCode();
				checkPause();
				if (responseCode == 200 || responseCode == 206) {
					if (data.getSize() == -1 || data.getSize() == 0 || data.getSize() < 50) {
						int contentLength = connection.getContentLength();
						if (contentLength > 60) {
							data.setSize(contentLength);
							db.newOrUpdate(data);
						}
					}
					checkPause();
					File targetFile = new File(data.getPath());
					if (!targetFile.exists()) {
						File dir = targetFile.getParentFile();
						if (dir.exists() || dir.mkdirs()) {
							targetFile.createNewFile();
						}
					}
					checkPause();
					InputStream is = connection.getInputStream();
					checkPause();
					byte[] buffer = new byte[4096];
					int len = 0;
					int total = 0;
					long currentTime = 0;
					long lastTime = System.currentTimeMillis();
					data.setStatus(DownloadStatus.LOADING);
					while ((len = is.read(buffer)) != -1) {
						checkPause();
						currentTime = System.currentTimeMillis();
						fileOutputStream.write(buffer, 0, len);
						total += len;
						data.setProgress(lastProgress + total);
						Logs.d(TAG, getId() + ":" + data.getName() + ":" + data.getProgress() + ":" + data.getSize());
						if (currentTime - lastTime > 1000) {
							db.newOrUpdate(data);
							listener.onProgress(data);
							lastTime = currentTime;
						}
						checkPause();
					}
					data.setStatus(DownloadStatus.DONE);
					db.newOrUpdate(data);
					listener.onProgress(data);
					fileOutputStream.close();
					is.close();
					isStop = true;
				} else {
					if (retryCount >= Const.MAX_RETRY_DOWNLOAD_SIZE) {
						isStop = true;
						fileOutputStream.close();
						return;
					}
					Logs.d(TAG, "getResponseCode:" + responseCode);
//					String url = getURL();
					String url = null;
					if (url != null) {
						Logs.d(TAG, "get URL:" + url);
						data.setUrl(url);
						db.newOrUpdate(data);
					}
					isStop = false;
					retryCount++;
				}
			} catch (PauseException e) {
				data.setStatus(DownloadStatus.PAUSE);
				isStop = true;
			} catch (MalformedURLException e) {
				data.setStatus(DownloadStatus.PAUSE);
				isStop = true;
				e.printStackTrace();
			} catch (ProtocolException e) {
				data.setStatus(DownloadStatus.PAUSE);
				isStop = true;
				e.printStackTrace();
			} catch (IOException e) {
				data.setStatus(DownloadStatus.PAUSE);
				isStop = true;
				e.printStackTrace();
			}
			db.newOrUpdate(data);
			listener.onProgress(data);
			super.run();
		}
		if (!isPause) {
			listener.onNext(data);
		}
	}

	private void checkPause() throws PauseException {
		if (data.getStatus() == DownloadStatus.DELETE || isPause) {
			throw new PauseException();
		}
	}

	private HttpURLConnection getHttpUrlConnection(boolean isRange, String url, long startPos, long endPos) throws MalformedURLException, IOException, ProtocolException {
		URL urls = new URL(url);
		HttpURLConnection connection = (HttpURLConnection) urls.openConnection();
		connection.setRequestMethod("GET");
		connection.setDoInput(true);
		connection.setUseCaches(false);
		connection.setConnectTimeout(Const.CONNECT_TIMEOUT);
		connection.setReadTimeout(Const.READ_TIMEOUT);
		if (isRange) {
			if (endPos > 0) {
				connection.addRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
			} else {
				connection.addRequestProperty("Range", "bytes=" + startPos + "-");
			}
		}
		return connection;
	}

//	public String getURL() {
//		VideoData videoById = haixueWebDataManager.getVideoById(data.getVid());
//		if (videoById != null && videoById.getVideoUrl() != null) {
//			return processVideoURL(videoById.getVideoUrl());
//		}
//		return null;
//	}
//
//	private String processVideoURL(String urlString) {
//		//判断是否是m3u8地址
//		int m3u8LastIndexOf = urlString.lastIndexOf("_phone.m3u8");
//		if (m3u8LastIndexOf != -1) {
//			int lastIndexOf = urlString.lastIndexOf("_phone/");
//			String subSequence = urlString.substring(0, lastIndexOf);
//			return subSequence + ".mp4";
//		} else {
//			return urlString;
//		}
//	}

	//	public String getURL1() {
	//		try {
	//			URL url = new URL(data.getUrl());
	//			return NOT_ENCODE_VIDEO_URL + url.getPath();
	//		} catch (MalformedURLException e) {
	//			e.printStackTrace();
	//		}
	//		return null;
	//	}

	public void pause() {
		this.isPause = true;
	}

	//	private Long getFilelength() {
	//		try {
	//			BasicHttpParams httpParameters = new BasicHttpParams();
	//			HttpConnectionParams.setConnectionTimeout(httpParameters,
	//					Const.CONNECT_TIMEOUT);
	//			HttpConnectionParams.setSoTimeout(httpParameters,
	//					Const.READ_TIMEOUT);
	//			HttpGet getMethod = new HttpGet(data.getUrl());
	//			HttpClient httpClient = new DefaultHttpClient();
	//			HttpResponse response = httpClient.execute(getMethod);
	//			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
	//				long contentLength = response.getEntity().getContentLength();
	//				return contentLength;
	//			}
	//		} catch (ClientProtocolException e) {
	//			e.printStackTrace();
	//		} catch (IOException e) {
	//			e.printStackTrace();
	//		}
	//		return (long) -1;
	//	}
}
